import os.path
# -*- coding: utf-8 -*-
#
###
#
# Copyright (C) 2009 yed_ <yed (a) vanyli (o) net>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#
###

import pycurl
import os, sys, time, threading
from pyfuploader.config import PyfuploadConfigHandler
from gettext import gettext as _
from optparse import OptionParser
#from abc import abstractmethod


class PyfuploadCore(object):

  cobj = None
  file = {}

  __project__ = 'pyfupload'
  __version__ = '0.2.2'
  host = None
  user = None
  pwd  = None
  
  _slave = None
  
  ''' remote file's path and URI '''
  target = {}

  ''' upload directories for each connection '''
  conn_dirs = {}

  ''' connections properties '''
  connections = {}

  ''' default connection '''
  default_connection = None

  ''' choosen connection '''
  choosen_connection = None

  ''' choosen directory '''
  choosen_directory = None



  def __init__(self):
    self._init_config()
    self._init_slave()

  def before_upload(self):
    pass

  def post_upload(self):
    pass

  #@abstractmethod
  def progress(self):
    raise Exception('you should inherit "progress" method')

  #@abstractmethod
  def debug_output(self, lvl, msg):
    raise Exception('you should inherit "debug_output" method')

  #@abstractmethod
  def set_default(self):
    raise Exception('you should inherit "set_default" method')

  def set_target(self):
    if not self.file.has_key('name'): return False
    host = self.connections[self.choosen_connection]['host']
    dirs = self.conn_dirs[self.choosen_connection][self.choosen_directory]['dirs']
    file = self.file['name']

    self.target['path'] = os.path.join(host, dirs, file)

    url = self.conn_dirs[self.choosen_connection][self.choosen_directory]['url']
    self.target['url'] =  os.path.join(url, file)


  def _init_slave(self):
    if not self._slave:
      pass
    self._slave = PyfuploadSlave(self)


  def _init_config(self):
    self.config = PyfuploadConfigHandler(self)
    for connection in self.config.sections():
      props = dict(self.config.items(connection))
      self.connections[connection] = props
      if props.has_key('default'):
        self.default_connection  = connection

      dirs = {}
      conn = PyfuploadConfigHandler(self, connection)
      for conn_dir in conn.sections():
        dirs[conn_dir] = dict(conn.items(conn_dir))
#        print dirs
      self.conn_dirs[connection] = dirs
#      print 'xxx', dirs

  def _init_curl(self):
    self.cobj = pycurl.Curl()
    self.cobj.setopt(pycurl.UPLOAD, 1)
    self.cobj.setopt(pycurl.NOPROGRESS, 0)
    self.cobj.setopt(pycurl.VERBOSE, 1)
    self.cobj.setopt(pycurl.PROGRESSFUNCTION, self.progress)
    self.cobj.setopt(pycurl.DEBUGFUNCTION, self.debug_output)


  def set_source(self, file):
    self.file['path'] = file
    self.file['name'] = os.path.basename(file)
    self.file['size'] = os.path.getsize(file)

  def set_connection(self, conn_name):
    try:
      self.choosen_connection = conn_name
    except:
      print( _("Choosen connection does not exists") )

  def set_directory(self, dir_name):
    try:
      #self.choosen_directory = self.conn_dirs[self.choosen_connection][dir_name]
      self.choosen_directory = dir_name
    except:
      print(_("Choosen directory does not exists"))

  def get_directory(self):
    return self.choosen_directory

  def get_user(self):
    return self.connections[self.choosen_connection]['user']

  def get_pwd(self):
    return self.connections[self.choosen_connection]['pwd']

  def upload(self):
    try:
      self._init_curl()
      self.cobj.setopt(pycurl.URL, self.target['path'])
      self.cobj.setopt(pycurl.USERPWD, ':'.join([self.get_user(), self.get_pwd()]))
      self.cobj.setopt(pycurl.INFILESIZE, self.file['size'])
      self.cobj.setopt(pycurl.READFUNCTION, open(self.file['path'], 'rb').read)
      self.cobj.perform()
    except Exception, inst:
      print( _("Error while file upload") )
      print inst.args
      self.cobj.close()
      sys.exit()

    self.cobj.close()

  @staticmethod
  def parse_params():
    usage = "usage %prog [options] filename connection connection_dir"
    parser = OptionParser(usage=usage)
    parser.add_option("-G", "--gtk", action="store_true", dest="interface", default=True, help="Run GTK interface [default]")
    parser.add_option("-C", "--cmd", action="store_false", dest="interface", help="Run only at command-line")

    (options, args) = parser.parse_args()

    if len(args) and os.path.isfile(args[0]):
      options.interface = False

    return [options, args]

  @staticmethod
  def print_version():
    return PyfuploadCore.__project__, PyfuploadCore.__version__

  def progress(self, download_t, download_d, upload_t, upload_d):
    pass

class PyfuploadSlave(threading.Thread):

  parent = None

  def __init__(self, parent):
    threading.Thread.__init__(self)
    self.parent = parent

  def set_parent(self, parent):
    self.parent = parent

  def run(self):
    self.parent.before_upload()
    self.parent.upload()
    self.parent.post_upload()
